﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace Batty
{
    public class LaserFire
    {
        public class LaserBlast
        {
            public Vector3 position;
            public Matrix orientation;
            public float speed = 2500.0f;
            public float life;
            public float size;
            public BoundingSphere sphere;
            public Model model;
        }

        #region Fields

        private Pondhawk game;

        private Model model;

        private Model ring;

        private LinkedList<LaserBlast> laserBlasts = new LinkedList<LaserBlast>();
        
        #endregion

        #region Properties

        public LinkedList<LaserBlast> LaserBlasts { get { return laserBlasts; } }

        #endregion

        #region Constructor and LoadContent

        public LaserFire(Pondhawk game)
        {
            this.game = game;

        }

        /// <summary>
        /// This function is called to load content into this component
        /// of our game.
        /// </summary>
        /// <param name="content">The content manager to load from.</param>
        public void LoadContent(ContentManager content)
        {
           // model = content.Load<Model>("LaserBlast");
            ring = content.Load<Model>("Ring2");
        }

        #endregion

        #region Update Function

        /// <summary>
        /// This function is called to update this component of our game
        /// to the current game time.
        /// </summary>
        /// <param name="gameTime"></param>
        public void Update(GameTime gameTime)
        {
            float delta = (float)gameTime.ElapsedGameTime.TotalSeconds;

            /*foreach (LaserBlast blast in laserBlasts)
            {
                Vector3 direction = Vector3.TransformNormal(new Vector3(0, 0, 1), blast.orientation);
                blast.position += direction * blast.speed * delta;
            }*/

            // Loop over all laser blasts in the list
            for (LinkedListNode<LaserBlast> blastNode = laserBlasts.First; blastNode != null; )
            {
                // blastNode is the current node and we set
                // nextBlast to the next node in the list
                LinkedListNode<LaserBlast> nextBlast = blastNode.Next;

                // This is the actual blast object we are working on 
                LaserBlast blast = blastNode.Value;

                // Update the position
                Vector3 direction = Vector3.TransformNormal(new Vector3(0, 0.0f, 1), blast.orientation);
                blast.position += direction * blast.speed * delta;

                // Decrease the life of the blast
                blast.life -= delta;
                
                blast.size += 0.001f;

                if (blast.life <= 0)
                {
                    // When done, remove from the list
                    laserBlasts.Remove(blastNode);
                //    lifeTime = blast.life;
                }

                //blast.sphere = model.Meshes[0].BoundingSphere;
                //blast.sphere = blast.sphere.Transform(model.Bones[0].Transform);
                blastNode = nextBlast;
            }

        }

        #endregion

        #region Draw Functions

        /// <summary>
        /// This function is called to draw this game component.
        /// </summary>
        /// <param name="graphics"></param>
        /// <param name="gameTime"></param>
        public void Draw(GraphicsDeviceManager graphics, GameTime gameTime)
        {
            //DrawModel(graphics, model, Matrix.CreateTranslation(0, 300, 0));
            foreach (LaserBlast blast in laserBlasts)
            {
                DrawModel(graphics, ring,  blast.orientation * Matrix.CreateScale(blast.size) * Matrix.CreateTranslation(blast.position));
            }
        }


        private void DrawModel(GraphicsDeviceManager graphics, Model model, Matrix world)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = transforms[mesh.ParentBone.Index] * world;
                    effect.View = game.Camera.View;
                    effect.Projection = game.Camera.Projection;
                }
                mesh.Draw();
            }
        }

        #endregion

        #region FireLaser Function

        public void FireLaser(Vector3 position, Matrix orientation, float maxthrust)
        {
            LaserBlast blast = new LaserBlast();
            blast.position = position;
            blast.model = ring;
            blast.orientation = orientation;
            blast.size = 0.0005f;
            blast.sphere = new BoundingSphere();
           // blast.sphere = model.Meshes[0].BoundingSphere;
           // blast.sphere = blast.sphere.Transform(model.Bones[0].Transform);
            /*if (maxthrust > 0.5f)
            {
                if (blast.speed <= 10000.0f)
                {
                    blast.speed = 5000.0f + (maxthrust * 1.75f);
                }
            }*/
            /*if (maxthrust > 1000)
            {
                blast.speed = maxthrust * 2.7f;      // cm/sec
            }
            else if (maxthrust > 500 && maxthrust < 1001)
            {
                blast.speed += 5.0f; // cm/sec
            }
            else
            {
                blast.speed = 5000.0f;      // cm/sec
            }*/
            blast.life = 0.1f;          // 2 seconds

            laserBlasts.AddLast(blast);
        }

        #endregion
    }
}
